package com.leadbank.springboot.example.util;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * 反射工具类。
 * 
 * 
 */
public class ReflectUtil {
    private static void getAllFieldsImpl(Class<?> clazz, Map<String, Field> fields) {
        if (clazz.equals(Object.class)) {
            return;
        }

        getAllFieldsImpl(clazz.getSuperclass(), fields);

        Field[] dFields = clazz.getDeclaredFields();
        for (Field field : dFields) {
            fields.put(field.getName(), field);
        }
    }

    public static Map<String, Field> getAllFields(Class<?> clazz) {
        Map<String, Field> fields = new HashMap<String, Field>();
        getAllFieldsImpl(clazz, fields);
        return fields;
    }

    public static Field getFieldByFieldName(Object obj, String fieldName) {
        for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass
                .getSuperclass()) {
            try {
                return superClass.getDeclaredField(fieldName);
            } catch (NoSuchFieldException e) {
            }
        }
        return null;
    }

    public static Object getValueByFieldName(Object obj, String fieldName)
            throws SecurityException,
            NoSuchFieldException,
            IllegalArgumentException,
            IllegalAccessException {
        Field field = getFieldByFieldName(obj, fieldName);
        Object value = null;
        if (field != null) {
            if (field.isAccessible()) {
                value = field.get(obj);
            } else {
                field.setAccessible(true);
                value = field.get(obj);
                field.setAccessible(false);
            }
        }
        return value;
    }

    public static void setValueByFieldName(Object obj, String fieldName, Object value)
            throws SecurityException,
            NoSuchFieldException,
            IllegalArgumentException,
            IllegalAccessException {
        Field field = obj.getClass().getDeclaredField(fieldName);
        if (field.isAccessible()) {
            field.set(obj, value);
        } else {
            field.setAccessible(true);
            field.set(obj, value);
            field.setAccessible(false);
        }
    }
}
